<!-- TODO(psimakov): use local YUI library -->
<link rel="stylesheet" type="text/css"
    href="http://yui.yahooapis.com/3.6.0/build/cssreset-context/cssreset-context-min.css">
<script
    src="http://yui.yahooapis.com/3.6.0/build/yui/yui.js"></script>
<link rel="stylesheet" type="text/css"
    href="/static/inputex-3.1.0/src/inputex/assets/skins/sam/inputex.css">
<script
    src="/static/inputex-3.1.0/src/loader.js" type='text/javascript'></script>
<script
    src="/static/inputex-3.1.0/lib/jsonPretty.js" type='text/javascript'></script>

<!-- TODO(psimakov): take styles out into a separate file -->
<style>
  div.status-message {
    width:400px;   /* adjust */
    top:15%;
    left:50%;
    margin-left: -200px;  /* half of the width */
    position:fixed;
    background-color: rgb(255, 255, 128);
    background-color: rgba(255, 255, 128, 0.5);
    transparency: 50%;
    text-align: center;
    padding: 16px;
    z-index: 999;
  }

  div.form {
    width: 700px;
    margin: 20px;
    padding: 15px;
    display: none;
    text-align: left;
  }
  div#formContainer fieldset {
    border: none;
    border-top: solid 1px #999999;
    border-bottom: solid 1px #999999;
    margin-bottom: 16px;
  }
  div#formContainer fieldset legend span {
    color: #505050;
    font-weight: bold;
    padding: 4px;
  }

  div.inputEx-Field {
    width: 500px;
    padding-top: 0.2em;
    color: #999999;
  }
  div.inputEx-Field textarea {
    width: 496px;
    max-width: 496px;
    height: 200px;
    border: solid 1px #999999;
    padding: 4px;
    border-left: 6px solid #999999;
  }
  div.inputEx-StringField-wrapper input {
    margin-top: 2px;
    margin-bottom: 2px;
    padding: 2px;
    text-align: left;
    border: solid 1px #999999;
  }
  div.inputEx-Field input {
    width: 100%;
    border-left: 6px solid #999999;
  }
  div.inputEx-CheckBox input {
    width: auto;
  }
  div.inputEx-DateField {
    width: 480px;
  }

  div.inputex-form-buttonbar {
    margin: 0px;
    padding-left: 8px;
    padding-top: 18px;
    border-top: solid 1px #9999FF;
    text-align: center;
  }
  div.inputex-form-buttonbar a {
    text-decoration: none;
    padding: 4px;
    padding-left: 16px;
    padding-right: 16px;
    margin-right: 16px;
    font-weight: bold;
    color: #000000;
  }
  a.inputex-list-link {
    float: right;
  }
  a.inputEx-Button {
    background-color: #666;
    color: #FFFFFF;
    padding: 4px;
    padding-left: 16px;
    padding-right: 16px;
    margin-left: 4px;
    margin-right: 4px;
    font-weight: bold;
    text-decoration: none;
  }

  .pull-right {
    float: right;
  }
</style>

<div class='status-message' id='formStatusMessage' style='display: none;'>&nbsp;</div>

<div style='width: 100%;' align='center' class='yui3-skin-sam yui-skin-sam'>
  <div class='form' id='formContainer'></div>
</div>

<!-- TODO(psimakov): take most of JS out into a separate file -->
<script type='text/javascript'>
  // server communications timeout
  var ajaxRpcTimeoutMillis = 15 * 1000;

  function cbShowMsg(text){
    elem = document.getElementById("formStatusMessage");
    elem.textContent = text;  // FF, Chrome
    elem.innerText = text;    // IE
    elem.style.display = "block";
  }

  function cbHideMsg(){
  elem = document.getElementById("formStatusMessage");
    elem.style.display = "none";
  }

  // set initial UI state
  document.getElementById("formContainer").style.display = "none";
  cbShowMsg("Loading...");

  // keep all our global objects here
  cb_global = {};

  // various URL's needed by the form
  cb_global.get_url = '{{ get_url }}';
  cb_global.save_url = '{{ save_url }}';
  cb_global.save_args = {{ save_args }};
  cb_global.exit_url = '{{ exit_url }}';

  // If this value is '', deletions are not allowed
  cb_global.delete_url = '{{ delete_url }}';

  // set home folder
  YUI_config.groups.inputex.base = '/static/inputex-3.1.0/src/';

  // here is the main method
  YUI({filter: "raw"}).use(
    {{ required_modules }},
    function (Y) {

      // here is the object schema
      var schema = {
        root : {{ schema }}
      };

      // inject inputex annotations
      {{ schema_annotations }}

      // build form definition from the json schema
      builder = new Y.inputEx.JsonSchema.Builder({
        'schemaIdentifierMap': schema
      });
      inputExDefinition = builder.schemaToInputEx(schema.root);

      // bind buttons
      inputExDefinition.buttons = [
        {type: 'submit-link', value: 'Save', onClick:function() {
            cbShowMsg("Saving...");

            // record current state
            var lastSavedFormValue = cb_global.form.getValue();

            // format request
            var request_save = cb_global.save_args;
            request_save.payload = JSON.stringify(lastSavedFormValue);

            // append xsrf_token if provided
            if (cb_global.xsrf_token) {
                request_save.xsrf_token = cb_global.xsrf_token;
            }

            // format request
            request_data = {"request": JSON.stringify(request_save)};

            // async post data to the server
            var url = cb_global.save_url;

            Y.io(url, {
              method: 'PUT',
              data: request_data,
              timeout : ajaxRpcTimeoutMillis,
              on: {
                  success: function(id, o, args) {
                    var json = JSON.parse(o.responseText);

                    if (json.status != 200) {
                      msg = "Unknown error (" + json.status + ").";
                      if (json.message) {
                        msg = json.message;
                      }
                      cbShowMsg("Server error; error code " + json.status + ". " + msg);
                      return
                    }

                    // save lastSavedFormValue
                    cb_global.lastSavedFormValue = lastSavedFormValue;

                    // update UI
                    cbShowMsg(json.message);
                    setTimeout(function(){ cbHideMsg(); }, 750);
                  },
                  failure : function (x,o) {
                      cbShowMsg("Server did not respond. Please reload the page to try again.");
                  }
              }
            });

            return false;
        }},

        {type: 'link', value: 'Close', onClick:function(e) {
          lastSavedFormValue = cb_global.lastSavedFormValue.toPrettyJSONString(true);
          now = cb_global.form.getValue().toPrettyJSONString(true);
          if (lastSavedFormValue == now || confirm("Abandon all changes?")) {
            window.location = cb_global.exit_url;
          }

        }}
      ];

      // optional delete button
      if (cb_global.delete_url != '') {
           delete_button = {type: 'link', value: 'Delete',
              className: 'inputEx-Button inputEx-Button-Link pull-right',
              onClick:function(e) {
                  if (confirm("Are you sure you want to delete this {{ type_label }}?")) {
                      var form = document.createElement('form');
                      form.method = 'post';
                      form.action = cb_global.delete_url;
                      document.body.appendChild(form);
                      form.submit();
                  }
              }
           };
           inputExDefinition.buttons.push(delete_button)
      }

      // create form and bind it to DOM
      inputExDefinition.parentEl = 'formContainer';
      cb_global.form = new Y.inputEx.Form(inputExDefinition);

      // async get data from the sever and push it into the form when ready
      var url = cb_global.get_url;

      // request data for object being edited
      Y.io(url, {
        method: 'GET',
        timeout : ajaxRpcTimeoutMillis,
        on: {
            success: function(id, o, args) {
              var json = JSON.parse(o.responseText);

              // check status code
              if (json.status != 200) {
                msg = "Unknown error (" + json.status + ").";
                if (json.message) {
                  msg = json.message;
                }
                cbShowMsg("Server error; error code " + json.status + ". " + msg);
                return
              }

              // check payload
              if (!json.payload) {
                cbShowMsg("Server error; server sent no payload.");
                return
              }

              // push payload into form
              payload = JSON.parse(json.payload);
              cb_global.form.setValue(payload);

              // record xsrf token if provided
              if (json.xsrf_token) {
                cb_global.xsrf_token = json.xsrf_token;
              } else {
                cb_global.xsrf_token = null;
              }

              // save lastSavedFormValue
              cb_global.original = payload;
              cb_global.lastSavedFormValue = payload;

              // it is better to set lastSavedFormValue to a cb_global.form.getValue(),
              // but it does not work for rich edit control as it has delayed loading
              // and may not be ready when this line above is executed

              // update ui state
              document.getElementById("formContainer").style.display = "block";
              cbShowMsg(json.message);
              setTimeout(function(){ cbHideMsg(); }, 750);
            },
            failure : function (x,o) {
                cbShowMsg("Server did not respond. Please reload the page to try again.");
            }
        }
      });

  });
</script>